<template>
  <div class="app-container">
    <div class="table-container">
      <!-- 搜索 -->
      <el-row class="filter-container no-select">
        <!-- 简单搜索 -->
        <el-col :span="24" class="simple-filter">
          <!-- 按钮功能区 -->
          <el-button plain type="primary" icon="el-icon-plus" @click="showAdd()">新增</el-button>
          <el-button plain type="success" icon="el-icon-edit" :disabled="filters.selectNumber !== 1" @click="dels">修改</el-button>
          <el-button plain type="danger" icon="el-icon-delete" :disabled="filters.selectNumber <= 0" @click="dels">删除</el-button>

          <!-- 简单搜索框区 -->
          <div class="simple-search">
            <el-input
              v-model="filters.searchText"
              class="input-with-select"
              placeholder="请输入内容"
              @keyup.enter.native="getList"
            >
              <el-button slot="append" icon="el-icon-search" title="搜索" @click="getList" />
            </el-input>

            <el-button type="primary" @click="showComplexFilter">高级搜索<i class="el-icon-zoom-in el-icon--right" />
            </el-button>

            <!-- 刷新 -->
            <el-button plain type="info" icon="el-icon-refresh" title="刷新" @click="getList" />
          </div>
        </el-col>
        <!-- 高级搜索 -->
        <el-col v-if="filters.isComplex" :span="24" class="complex-filter">
          <el-collapse-transition>
            <el-form :ref="filters.formRef" :model="filters.whereFields" label-width="100px" class="pane">
              <el-row :gutter="10">
                <el-col :xs="12" :sm="8" :md="6" :lg="5" :xl="4">
                  <el-form-item label="角色编码" prop="code">
                    <el-input v-model="filters.whereFields.code" placeholder="请输入角色编码" />
                  </el-form-item>
                </el-col>

                <el-col :xs="12" :sm="8" :md="6" :lg="5" :xl="4">
                  <el-form-item label="角色名称" prop="title">
                    <el-input v-model="filters.whereFields.title" placeholder="请输入角色名称" />
                  </el-form-item>
                </el-col>

                <el-col :xs="12" :sm="8" :md="6" :lg="5" :xl="4">
                  <el-form-item label="状态" prop="status">
                    <el-select v-model="filters.whereFields.status" clearable placeholder="请选择状态">
                      <el-option label="禁用" value="0" />
                      <el-option label="正常" value="1" />
                    </el-select>
                  </el-form-item>
                </el-col>

                <el-col :xs="12" :sm="8" :md="6" :lg="5" :xl="4">
                  <el-form-item no-label class="no-label">
                    <el-button @click="resetComplexForm">重置条件</el-button>
                    <el-button type="primary" @click="getList">搜索</el-button>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
          </el-collapse-transition>
        </el-col>
      </el-row>

      <!-- 数据表格 -->
      <el-table
        v-loading="loading"
        border
        :data="tableData"
        class="filter-table"
        height="calc(100vh - 302px)"
        @selection-change="selectionChange"
        @sort-change="changeSort"
      >

        <el-table-column
          type="selection"
          align="center"
          width="40"
        />

        <el-table-column
          prop="id"
          label="ID"
          align="center"
          width="80"
          sortable
        />

        <el-table-column
          prop="code"
          label="角色编码"
          sortable
        />

        <el-table-column
          prop="title"
          label="角色名称"
          sortable
        />

        <el-table-column
          prop="sort"
          label="排序"
          align="center"
          width="100px"
          sortable
        />

        <el-table-column
          prop="status"
          label="状态"
          align="center"
          width="100px"
          sortable
        >
          <template slot-scope="scope">
            <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" @change="updateStatus($event, scope.row, scope.$index)" />
          </template>
        </el-table-column>

        <el-table-column
          prop="created_at"
          label="创建时间"
          align="center"
          width="154"
          sortable
        >
          <template slot-scope="scope">
            <span>{{ scope.row.created_at | parseTime }}</span>
          </template>
        </el-table-column>

        <el-table-column
          fixed="right"
          label="操作"
          align="center"
          width="140px"
        >
          <template slot-scope="scope">
            <el-button type="text" icon="el-icon-edit">修改</el-button>
            <el-button type="text" icon="el-icon-delete" @click="del(scope.row)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 表格分页 -->
      <div class="filter-pagination no-select">
        <div v-show="filters.selectNumber > 0" class="select-text">共选择了<span
          class="number"
        >{{ filters.selectNumber }}</span>条数据!
        </div>
        <el-pagination
          :current-page="currentPage"
          :page-sizes="[5, 10, 15, 20, 30, 40, 50, 100]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="tableTotal"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 新增角色 -->
    <el-dialog
      :width="dialogWidth"
      :show-close="false"
      :visible.sync="dialogRoleNodeVisible"
      class="role-add"
    >
      <el-steps :active="active" finish-status="success">
        <el-step :title="actionName" icon="el-icon-edit-outline" />
        <el-step title="设置权限" icon="el-icon-setting" />
        <el-step title="完成" icon="el-icon-success" />
      </el-steps>

      <el-form ref="form" :model="form" label-width="80px" :rules="roleRules">
        <div v-if="active == 0" class="role-info">
          <el-form-item label="名称" prop="name">
            <el-input v-model="form.name" />
          </el-form-item>

          <el-form-item label="排序" prop="sort">
            <el-input v-model="form.sort" />
          </el-form-item>

          <el-form-item label="状态">
            <el-radio-group v-model="form.status">
              <el-radio :label="0" border>禁用</el-radio>
              <el-radio :label="1" border>开启</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item label="描述" prop="description">
            <el-input v-model="form.description" type="textarea" />
          </el-form-item>
        </div>

        <div v-else-if="active == 1" class="role-node">
          <el-checkbox-group v-model="form.node_id">
            <div v-for="module in this.nodes" class="nodes">
              <div class="module">
                <el-checkbox :key="module.id" :label="module.id" @change="((val)=>{handleCheckedChange(val, module)})">{{ module.title }}</el-checkbox>
              </div>

              <dl v-for="controller in module.children">
                <dt>
                  <el-checkbox :key="controller.id" :label="controller.id" @change="((val)=>{handleCheckedChange(val, controller)})">{{ controller.title }}</el-checkbox>
                </dt>
                <dd v-for="action in controller.children">
                  <el-checkbox :key="action.id" :label="action.id" @change="((val)=>{handleCheckedChange(val, action, controller.children, [module.id, controller.id])})">{{ action.title }}</el-checkbox>
                </dd>
              </dl>
            </div>
          </el-checkbox-group>
        </div>

        <div v-else class="role-end">
          <div class="add-success">
            <div class="class text">
              <i class="el-icon-check" />{{ actionName }}
              【<span class="role-name">{{ form.name }}</span>】成功！
            </div>
          </div>
        </div>
      </el-form>
      <div v-if="active == 0" slot="footer" class="dialog-footer">
        <el-button @click="dialogRoleNodeVisible = false">取 消</el-button>
        <el-button type="primary" @click="setRoleNode">设置权限</el-button>
      </div>

      <div v-else-if="active == 1" slot="footer" class="dialog-footer">
        <el-button @click="active = 0">上一步</el-button>
        <el-button type="primary" :loading="isCreatedLoading" @click="createdRole">{{ actionName }}</el-button>
      </div>

      <div v-else slot="footer" class="dialog-footer">
        <el-button type="success" class="full-btn" @click="hideDialog()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import validate from '@/utils/validate'
import search from '@/utils/search'
import { getLStorage, MD5, saveLStorage } from '@/utils/index'
import { disable, enable, dels, search as searchApi } from '@/api/sys/role'
import { tree as getNodeList } from '@/api/sys/node'

export default {
  name: 'RoleList'
  , data() {
    const validateName = (rule, value, callback) => {
      const nameMaxLength = 32
      if (!value) {
        callback(new Error('请输入名称'))
      } else if (value.length > nameMaxLength) {
        callback(new Error('名称不能超过' + nameMaxLength + '字符'))
      } else {
        callback()
      }
    }

    const validateSort = (rule, value, callback) => {
      const minNum = 1
      const maxNum = 255
      if (!this.valiInt(value)) {
        callback(new Error('排序必须为数字'))
      } else if (value < minNum || value > maxNum) {
        callback(new Error('排序为' + minNum + '~' + maxNum + '之间的数字'))
      } else {
        callback()
      }
    }

    const validateDesc = (rule, value, callback) => {
      if (!value) {
        callback(new Error('请输入描述'))
      } else {
        callback()
      }
    }

    return {
      prohibitDelIds: [1]
      , searchFields: [
        { 'name': 'id', 'type': 'integer' }
        , { 'name': 'code', 'type': 'string' }
        , { 'name': 'title', 'type': 'string' }
        , { 'name': 'status', 'type': 'integer', 'selection': true, 'selectionList': [
          { 'value': '0', 'label': '禁用' }
          , { 'value': '1', 'label': '正常' }
        ] }
      ]
      , filters: {
        isComplex: false
        , formRef: ''
        , selectNumber: 0
        , searchText: ''
        , whereFields: {
          title: undefined
          , type: undefined
          , status: undefined
          , created_at: undefined
        }
      }
      , loading: false
      , tableSelection: undefined
      , pageSize: 10
      , currentPage: 1
      , tableTotal: 0
      , tableData: []
      //, sort: []
      // 新增或修改
      , active: 0
      , dialogRoleNodeVisible: false
      , form: {
        name: ''
        , sort: 1
        , status: 1
        , description: ''
        , node_id: []
      }
      , roleRules: {
        name: [{ required: true, trigger: 'blur', validator: validateName }]
        , sort: [{ type: 'number', trigger: 'blur', validator: validateSort }]
        , description: [{ required: true, trigger: 'blur', validator: validateDesc }]
      }
    }
  }
  , computed: {
    ...mapGetters([
      'fullHeight'
      , 'pageList'
    ])

    , dialogWidth() {
      console.log(this.active)
      if (this.active === 1) {
        return '50%'
      }
      return '440px'
    }
    // 判断是否能创建角色
    , isCreated() {
      return !(!this.isSetNode || !this.form.node_id || this.form.node_id.length < 3)
    }
    // 判断角色信息是否完整
    , isSetNode() {
      var isTrue = true
      this.$refs.form.validate((res, res1) => {
        for (var err in res1) {
          if (['name', 'sort', 'description'].indexOf(err) !== -1) {
            isTrue = false
            break
          }
        }
      })
      return isTrue
    }
    // 操作名称
    , actionName() {
      return (this.isAdd ? '新增' : '修改') + '角色'
    }
  }
  , created() {
    // 设置表单ref
    this.filters.formRef = this.getIsComplexFiltersKey()
    // 加载是否展示高级搜索
    var isComplex = getLStorage(this.filters.formRef)
    if (validate.notEmpty(isComplex)) {
      this.filters.isComplex = isComplex
    }

    // 获取列表数据
    this.getList()
  }
  , methods: {
    getList() {
      this.loading = true
      searchApi(search.getQueryParams(this)).then(res => {
        var { data } = res
        if (this.currentPage > data.totalRows) {
          this.currentPage = data.totalRows
          this.getList()
        }

        this.tableData = data.rows
        this.tableTotal = data.total
        this.loading = false
      })
    }

    , dels() {
      if (this.filters.selectNumber) {
        var ids = this.tableSelection.map(val => val.id).join(',')
        this.$confirm('是否确认删除ID为[' + ids + ']的数据项?', '警告', {
          confirmButtonText: '确定'
          , cancelButtonText: '取消'
          , type: 'warning'
        }).then(() => {
          dels(this.tableSelection.map(val => val.id).join(',')).then(res => {
            // 获取数据
            this.getList()
            // 提示信息
            this.$message({ message: res.message, type: 'success' })
          })
        }).catch(() => {})
      }
    }

    // 单条删除
    , del(data) {
      this.$confirm('是否确认删除角色[' + data.title + ']数据项？', '警告', {
        confirmButtonText: '确定'
        , cancelButtonText: '取消'
        , type: 'warning'
      }).then(() => {
        dels(data.id).then(res => {
          // 获取数据
          this.getList()
          // 提示信息
          this.$message({ message: res.message, type: 'success' })
        })
      }).catch(() => {
      })
    }

    // 设置用户状态
    , updateStatus(event, data, index) {
      this.tableData[index].status = event === 1 ? 0 : 1
      this.$confirm('确认' + (event ? '启用' : '禁用') + '角色[' + data.title + ']？', '警告', {
        confirmButtonText: '确定'
        , cancelButtonText: '取消'
        , type: 'warning'
      }).then(() => {
        (event ? disable(data.id) : enable(data.id)).then(res => {
          this.tableData[index].status = event
          // 提示信息
          this.$message({ message: res.message, type: 'success' })
        })
      }).catch(() => {
      })
    }

    , handleSizeChange(val) {
      this.pageSize = val
      var maxPage = Math.ceil(this.tableTotal / val)
      if (maxPage < this.currentPage) {
        this.currentPage = maxPage
      }
      this.getList()
    }

    , handleCurrentChange(val) {
      this.currentPage = val
      this.getList()
    }

    // 表格数据选择
    , selectionChange(val) {
      this.tableSelection = val
      // 更新选择数量
      this.filters.selectNumber = validate.notEmpty(val) ? (val.filter(row => this.prohibitDelIds.indexOf(row.id) === -1)).length : 0
    }

    // 展示/隐藏高级搜索
    , showComplexFilter() {
      this.filters.isComplex = !this.filters.isComplex
      saveLStorage(this.filters.formRef, this.filters.isComplex)
      // 隐藏时重置表单
      if (!this.filters.isComplex) {
        this.resetComplexForm()
      }
    }

    // 重置高级搜索表单
    , resetComplexForm() {
      this.$refs[this.filters.formRef].resetFields()
      // 重新获取数据
      this.getList()
    }

    , getIsComplexFiltersKey() {
      return MD5(this.$route.path + this.$options.name)
    }

    // 表格排序
    , changeSort(val) {
      this.sort = val
      this.getList()
    }

    // 新增显示弹窗
    , showAdd() {
      // 新增
      this.isAdd = true

      // 判断是否有修改回填数据，有的话清除
      if (this.form.id && this.form.id > 0) {
        delete this.form.id
        this.form.name = ''
        this.form.sort = 1
        this.form.status = 1
        this.form.description = ''
        this.form.node_id = []
      }

      // 显示弹窗
      this.dialogRoleNodeVisible = true
    }
    // 隐藏弹窗框
    , hideDialog() {
      // 隐藏弹框
      this.dialogRoleNodeVisible = false
      // tab切换到0
      this.active = 0
      // 清空表单数据
      delete this.form.id
      this.form.name = ''
      this.form.sort = 1
      this.form.status = 1
      this.form.description = ''
      this.form.node_id = []
      // 将状态设置为新增
      this.isAdd = true
    }
    // 修改
    , handleEdit(index, row) {
      // 修改
      this.isAdd = false

      // 获取角色权限
      roleInfo({ id: row.id }).then(res => {
        res = res.data
        // 重置值
        for (var i in this.form) {
          this.form[i] = res[i]
        }

        // 设置id
        this.form['id'] = res['id']
        // 显示
        this.dialogRoleNodeVisible = true
      }).catch(res => {})
    }
    // 跳转到设置权限
    , setRoleNode() {
      if (this.isSetNode) {
        if (!this.nodes) {
          // 获取节点数据
          getNodeList().then(res => {
            this.nodes = []
            this.nodes.push(...res.data)
            this.active = 1
            console.log('节点数据：', this.nodes)
          }).catch(res => {
            console.log('加载数据错误：', res)
          })
        } else {
          this.active = 1
        }
      }
    }
    // 提交并创建角色
    , createdRole() {
      // 判断角色信息是否完整
      if (!this.isSetNode) {
        this.active = 0
        return this.active
      }

      // 判断权限是否设置
      if (!this.isCreated) {
        return this.$message({
          type: 'error'
          , message: '请设置' + this.$t('role.node')
        })
      }

      if (!this.isAdd && (!this.form.id || this.form.id < 1)) {
        return this.$message({
          type: 'error'
          , message: '参数错误，请刷新后重新操作！'
        })
      }

      this.isCreatedLoading = true
      // 判断是修改还是新增
      if (this.isAdd) {
        // 保存角色
        roleAdd(this.form).then(res => {
          this.isCreatedLoading = false
          this.active = 2
          // 重新加载
          this.load()
        }).catch(res => {
          this.isCreatedLoading = false
        })
      } else {
        // 修改角色
        roleEdit(this.form).then(res => {
          this.isCreatedLoading = false
          this.active = 2
          // 重新加载
          this.load()
        }).catch(res => {
          this.isCreatedLoading = false
        })
      }
    }
    , getNodeId(nodes, ids) {
      // 初始化
      this.checkedIds = ids === true ? this.checkedIds : []
      // 处理id
      this.checkedIds.push(nodes['id'])
      if (nodes['children'].length) {
        // 处理子节点
        for (var i in nodes['children']) {
          this.getNodeId(nodes['children'][i], true)
        }
      }
      // 返回ids
      return this.checkedIds
    }
    // 权限选择
    , handleCheckedChange(value, item, peer, parentIds) {
      var items = this.getNodeId(item)
      // 处理节点关联
      if (item.type === 'module') {
        if (value) {
          // 全选
          for (var i of items) {
            this.form.node_id.push(i)
          }
        } else {
          // 取消
          this.form.node_id = this.form.node_id.filter((val) => {
            return items.indexOf(val) === -1
          })
        }
      } else if (item.type === 'controller') {
        if (value) {
          items.push(item.pid)
          for (var ii of items) {
            this.form.node_id.push(ii)
          }
        } else {
          // 过滤没选中的值
          items = items.filter(val => {
            return this.form.node_id.indexOf(val) !== -1
          })
          // 处理是否是清空
          if (items.length + 1 === this.form.node_id.length) items.push(item.pid)
          // 取消
          this.form.node_id = this.form.node_id.filter((val) => {
            return items.indexOf(val) === -1
          })
        }
      } else {
        if (value) {
          items = items.concat(parentIds)
          for (var iii of items) {
            if (this.form.node_id.indexOf(iii) === -1) {
              this.form.node_id.push(iii)
            }
          }

          if (item.value !== 'list') {
            for (var node of peer) {
              if (node.value === 'list') {
                this.form.node_id.push(node.id)
                break
              }
            }
          }
        } else {
          if (item.value === 'list') {
            // 获取同级被选中的id
            items = []
            for (var peerId of peer) {
              if (this.form.node_id.indexOf(peerId['id']) !== -1) {
                items.push(peerId['id'])
              }
            }

            if (items.length + 2 === this.form.node_id.length) {
              this.form.node_id = []
            } else {
              items.push(item['pid'])
              this.form.node_id = this.form.node_id.filter((val) => {
                return items.indexOf(val) === -1
              })
            }
          }
        }
      }

      // 选中值去重
      this.form.node_id = this.unique(this.form.node_id)
    }
  }
}
</script>

<style lang="scss">
  .app-main {
    background-color: #f2f2f2;

    .table-container {
      .filter-table {
        .el-table__header th {
          background: #f2f2f2;
        }

        .el-table__header tr th:nth-last-child(2),
        .el-table__body .el-table__row td:last-child {
          border-right-width: 0;
        }

        .el-table__body td.el-table-column--selection .cell {
          padding-right: 0.625rem;
        }
      }

      .filter-pagination {
        .el-pagination {
          .btn-prev,
          .btn-next,
          .el-pager li {
            background-color: transparent;
          }
        }
      }
    }
  }
</style>

<style lang="scss" scoped>
  @import "@/styles/element-variables.scss";

  $bg: #fff;
  $space: 0.625rem;

  .table-container {
    background-color: $bg;
    border: 1px solid $--border-color-light;
    border-radius: 4px;
    overflow: hidden;

    .filter-container {
      background-color: $bg;
      padding: 0;

      .simple-filter {
        padding: $space;
        position: relative;

        .simple-search {
          position: absolute;
          right: $space;
          top: $space;

          .input-with-select {
            width: 13.75rem;
            margin-right: $space;
          }
        }
      }

      .complex-filter {
        padding: $space $space 0 $space;
        border-top: 1px solid $--border-color-light;

        .el-form-item {
          margin-bottom: $space;
        }
      }
    }

    .filter-table {
      border-left-width: 0;

      &::after,
      &::before {
        background-color: transparent;
      }
    }

    .filter-pagination {
      $elPaginationHeight: 32px;
      $paginationHeight: 40px;

      position: relative;
      height: $paginationHeight;
      line-height: $paginationHeight;
      padding: 0 $space;
      font-size: 13px;
      background-color: #fafafa;
      color: #606266;
      border-top: 1px solid $--border-color-light;

      .select-text .number {
        color: red;
        padding: 0 calc(#{$space} / 2);
      }

      .el-pagination {
        position: absolute;
        height: $elPaginationHeight;
        line-height: $elPaginationHeight;
        right: $space;
        top: 0;
        margin: calc((#{$paginationHeight} - #{$elPaginationHeight}) / 2) 0;
      }
    }
  }

  // 处理弹框
  .role-add{
    .role-info{
      padding: 25px 14px 0 0;
    }

    // 权限样式
    .role-node{
      .nodes{
        margin-top: 25px;
        border: 1px solid #ccc;
        .module{
          font-size: 14px;
          height: 28px;
          line-height: 28px;
          border-bottom: 1px solid #ccc;
          padding-left: 10px;
        }
        dl{
          position: relative;
          padding-left: 8.6em;
          margin: 0;
          font-size: 14px;
          line-height: 2em;
          border-bottom: 1px solid #ccc;
          &:last-child{
            border-bottom-width: 0;
          }
          dd{
            position: relative;
            height: 2em;
            display: inline-block;
            padding: 0 0.6em 0 0.6em;
            margin: 0;
          }
          dt{
            display: inline-block;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            background-color: oldlace;
            width: 8.6em;
            margin-left: 0;
            padding-left: 10px;
          }
        }
      }
    }

    // 成功样式
    .role-end {
      .add-success {
        i{
          position: relative;
          top: 3px;
          font-size: 32px;
          color: #67C23A;
          font-weight: bold;
        }
        .role-name{
          color: red;
          font-weight: bold;
        }
        padding: 60px 0;
        font-size: 16px;
        line-height: 32px;
        text-align: center;
      }
    }
  }
</style>
